/**
 * 
 */
package com.jsync.events;

import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.util.HashMap;
import java.util.Map;

import com.jcraft.jsch.ChannelSftp;
import com.jcraft.jsch.JSch;
import com.jcraft.jsch.Session;
import com.jsync.model.Resource;
import com.jsync.model.ResourceProfile;

/**
 * @author prabz
 *
 */
public class SFTPSyncTrigger implements SyncTrigger<Resource> {

	private Map<String, Session> pool;
	
	public SFTPSyncTrigger(){
		pool = new HashMap<String, Session>();
	}
	
	/**
	 * @param user
	 * @param pwd
	 * @param host
	 * @param port
	 * @return
	 */
	private Session connect(String user, String pwd, String host, int port){
		Session session = null;
	    try{
	        JSch jsch=new JSch();
	        //String host=null;
	        //String user=host.substring(0, host.indexOf('@'));
	        //host=host.substring(host.indexOf('@')+1);
	        //int port=22;
	        String key = user+"@"+host+":"+port;
	        session = pool.get(key);
	        if(session==null){
		        session=jsch.getSession(user, host, port);
		        session.setPassword(pwd);
		        java.util.Properties config = new java.util.Properties(); 
		        config.put("StrictHostKeyChecking", "no");
		        session.setConfig(config);
		        //put in pool
		        pool.put(key, session);
	        }
	        if(!session.isConnected())
	        	session.connect();
	        //ChannelSftp channel=(ChannelSftp)session.openChannel("sftp");
	        //channel.connect();	        
	    }catch(Exception ex){
	    	ex.printStackTrace();
	    }
	    return session;
	}
	
	/* (non-Javadoc)
	 * @see com.jsync.events.SyncTrigger#send(java.lang.Object)
	 */
	@Override
	public boolean send(Resource resource) {
		// TODO Auto-generated method stub
		boolean flag = false;
		ChannelSftp channel = null;
		InputStream fis = null;
		try{			
			ResourceProfile rp = resource.getProfile();
			Session session = connect(rp.getDestinationUser(), rp.getDestinationPass(), rp.getHost(), rp.getPort());
			if(session!=null && session.isConnected()){
				channel=(ChannelSftp)session.openChannel("sftp");
				channel.connect();
				String path = rp.getSource()+File.separator+resource.getName();
				String dest = rp.getDestination()+"/"+resource.getName().replace("\\", "/");
				File file = new File(path);
				// ADD, DELETE, RENAME, MODIFY
				if(Resource.Operation.ADD.equals(resource.getChange()) || 
						Resource.Operation.MODIFY.equals(resource.getChange())){
					if(file.isDirectory()){
						channel.mkdir(dest);
					}else{
						fis = new FileInputStream(file);
						channel.put(fis, dest);
						fis.close();
					}
				}else if(Resource.Operation.DELETE.equals(resource.getChange())){
					try{
						channel.rm(dest);
					}catch(Exception ex){
						channel.rmdir(dest);
					}
				}else if(Resource.Operation.RENAME.equals(resource.getChange())){
					String rpath = rp.getDestination()+"/"+resource.getName().replace("\\", "/");
					String rdest = rp.getDestination()+"/"+resource.getNewName().replace("\\", "/");
					channel.rename(rpath, rdest);
				}				
				channel.disconnect();
				flag = true;
			}						
		}catch(Exception ex){
			ex.printStackTrace();
			if(channel!=null)
				channel.disconnect();
			try{
				if(fis!=null)
					fis.close();
			}catch(IOException io){
				io.printStackTrace();
			}
		}
		return flag;
	}

	/* (non-Javadoc)
	 * @see com.jsync.events.SyncTrigger#receive(java.lang.Object)
	 */
	@Override
	public InputStreamReader receive(Resource resource) {
		// TODO Auto-generated method stub
		return null;
	}

}
